using System;
using System.ComponentModel;
using System.Drawing;
using System.Windows.Forms;

namespace AutoUpdater
{
    public partial class UpgradeForm : Form
    {
        private Timer _mainFormCloseTimer;
        private readonly UpgradeManager _upgradeManager;
        private bool _isUpgrading;
        private bool _connectionEstablished = false; // 标记是否已成功连接服务器

        // 设计器生成的控件
        private Label lblStatus;
        private ProgressBar progressDownload;
        private Button btnPostpone;
        private TextBox txtDescription;
        private Label lblDownloadProgress;
        private ProgressBar progressInstall;
        private Label lblInstallProgress;
        private Container components;


        public UpgradeForm(string currentVersion)
        {
            InitializeComponents();
            InitializeUI();
            InitializeMainFormCloseTimer();

            _upgradeManager = new UpgradeManager(currentVersion);
            RegisterUpgradeEvents();

            // 初始状态：最小化到任务栏（连接服务器前不显示窗口）
            this.WindowState = FormWindowState.Minimized;
            this.ShowInTaskbar = true; // 确保在任务栏显示
        }

        // 初始化Windows控件（替代Designer.cs）
        private void InitializeComponents()
        {
            this.components = new System.ComponentModel.Container();
            this.lblStatus = new System.Windows.Forms.Label();
            this.progressDownload = new System.Windows.Forms.ProgressBar();
            this.btnPostpone = new System.Windows.Forms.Button();
            this.txtDescription = new System.Windows.Forms.TextBox();
            this.lblDownloadProgress = new System.Windows.Forms.Label();
            this.progressInstall = new System.Windows.Forms.ProgressBar();
            this.lblInstallProgress = new System.Windows.Forms.Label();
            this.SuspendLayout();

            // lblStatus
            this.lblStatus.AutoSize = true;
            this.lblStatus.Location = new System.Drawing.Point(12, 15);
            this.lblStatus.Name = "lblStatus";
            this.lblStatus.Size = new System.Drawing.Size(53, 12);
            this.lblStatus.TabIndex = 0;
            this.lblStatus.Text = "准备中...";

            // progressDownload
            this.progressDownload.Location = new System.Drawing.Point(14, 57);
            this.progressDownload.Name = "progressDownload";
            this.progressDownload.Size = new System.Drawing.Size(464, 23);
            this.progressDownload.TabIndex = 1;

            // btnPostpone
            this.btnPostpone.Location = new System.Drawing.Point(403, 225);
            this.btnPostpone.Name = "btnPostpone";
            this.btnPostpone.Size = new System.Drawing.Size(75, 23);
            this.btnPostpone.TabIndex = 3;
            this.btnPostpone.Text = "稍后升级";
            this.btnPostpone.UseVisualStyleBackColor = true;
            this.btnPostpone.Click += new System.EventHandler(this.btnPostpone_Click);

            // txtDescription
            this.txtDescription.Location = new System.Drawing.Point(14, 125);
            this.txtDescription.Multiline = true;
            this.txtDescription.Name = "txtDescription";
            this.txtDescription.ReadOnly = true;
            this.txtDescription.ScrollBars = System.Windows.Forms.ScrollBars.Vertical;
            this.txtDescription.Size = new System.Drawing.Size(464, 85);
            this.txtDescription.TabIndex = 4;

            // lblDownloadProgress
            this.lblDownloadProgress.AutoSize = true;
            this.lblDownloadProgress.Location = new System.Drawing.Point(12, 40);
            this.lblDownloadProgress.Name = "lblDownloadProgress";
            this.lblDownloadProgress.Size = new System.Drawing.Size(65, 12);
            this.lblDownloadProgress.TabIndex = 5;
            this.lblDownloadProgress.Text = "下载进度：";

            // progressInstall
            this.progressInstall.Location = new System.Drawing.Point(14, 100);
            this.progressInstall.Name = "progressInstall";
            this.progressInstall.Size = new System.Drawing.Size(464, 23);
            this.progressInstall.TabIndex = 6;

            // lblInstallProgress
            this.lblInstallProgress.AutoSize = true;
            this.lblInstallProgress.Location = new System.Drawing.Point(12, 83);
            this.lblInstallProgress.Name = "lblInstallProgress";
            this.lblInstallProgress.Size = new System.Drawing.Size(65, 12);
            this.lblInstallProgress.TabIndex = 7;
            this.lblInstallProgress.Text = "安装进度：";

            // UpgradeForm
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 12F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(490, 260);
            this.Controls.Add(this.lblInstallProgress);
            this.Controls.Add(this.progressInstall);
            this.Controls.Add(this.lblDownloadProgress);
            this.Controls.Add(this.txtDescription);
            this.Controls.Add(this.btnPostpone);
            this.Controls.Add(this.progressDownload);
            this.Controls.Add(this.lblStatus);
            this.FormBorderStyle = System.Windows.Forms.FormBorderStyle.FixedSingle;
            this.MaximizeBox = false;
            this.MinimizeBox = false;
            this.Name = "UpgradeForm";
            this.Text = "程序升级";
            this.FormClosing += new System.Windows.Forms.FormClosingEventHandler(this.UpgradeForm_FormClosing);
            this.Load += new System.EventHandler(this.UpgradeForm_Load);
            this.ResumeLayout(false);
            this.PerformLayout();
        }

        private void InitializeUI()
        {
            this.Text = "程序升级";
            this.StartPosition = FormStartPosition.CenterScreen;
            this.MaximizeBox = false;
            this.MinimizeBox = true; // 启用最小化
            this.FormBorderStyle = FormBorderStyle.FixedSingle;
            this.Size = new Size(510, 300);

            // 进度条初始化
            progressDownload.Maximum = 100;
            progressInstall.Maximum = 100;
            progressDownload.Value = 0;
            progressInstall.Value = 0;
            progressInstall.Visible = false;
            lblInstallProgress.Visible = false;

            // 按钮状态（仅处理推迟按钮）
            btnPostpone.Enabled = true;
        }

        private void InitializeMainFormCloseTimer()
        {
            _mainFormCloseTimer = new Timer();
            _mainFormCloseTimer.Interval = 3000; // 3秒后关闭主窗口
            _mainFormCloseTimer.Tick += (sender, e) =>
            {
                _mainFormCloseTimer.Stop();
                _mainFormCloseTimer.Dispose();
                this.Close();
            };
        }

        private void RegisterUpgradeEvents()
        {
            _upgradeManager.StatusChanged += OnUpgradeStatusChanged;
            _upgradeManager.DownloadProgressChanged += OnDownloadProgressChanged;
            _upgradeManager.InstallProgressChanged += OnInstallProgressChanged;
            _upgradeManager.StatusMessageUpdated += OnStatusMessageUpdated;
            // 新增：服务器连接成功事件
            _upgradeManager.ServerConnected += OnServerConnected;
        }

        private async void UpgradeForm_Load(object sender, EventArgs e)
        {
            lblStatus.Text = "正在检查更新...";
            await _upgradeManager.StartUpgradeProcess();
        }

        /// <summary>
        /// 服务器连接成功后显示窗口
        /// </summary>
        private void OnServerConnected()
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(OnServerConnected));
                return;
            }

            _connectionEstablished = true;
            // 从任务栏恢复窗口
            this.WindowState = FormWindowState.Normal;
            this.BringToFront();
        }

        private void OnUpgradeStatusChanged(UpgradeStatus status)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<UpgradeStatus>(OnUpgradeStatusChanged), status);
                return;
            }

            switch (status)
            {
                case UpgradeStatus.Starting:
                    lblStatus.Text = "初始化升级组件...";
                    break;
                case UpgradeStatus.ServerConnectionFailed:
                    // 连接服务器失败（已达最大重试次数）
                    lblStatus.Text = "连接服务器超时";
                    btnPostpone.Enabled = false;
                    _isUpgrading = false;

                    // 如果从未成功连接过服务器，此时需要显示窗口
                    if (!_connectionEstablished)
                    {
                        this.WindowState = FormWindowState.Normal;
                        this.BringToFront();
                    }

                    // 显示超时提示
                    //ShowNotificationWindow( title: "连接失败",
                    //                        content: "连接服务器超时，已重试5次\n请检查网络后重试",
                    //                        type: NotificationType.Error
                    //                    );
                    // 3秒后自动关闭窗口
                    _mainFormCloseTimer.Interval = 5000;
                    _mainFormCloseTimer.Start();
                    break;
                case UpgradeStatus.PreUpgradeSuccess:
                    lblStatus.Text = "获取服务器配置成功";
                    // 移除立即升级按钮相关逻辑，改为自动开始升级
                    if (!_isUpgrading && _connectionEstablished)
                    {
                        _upgradeManager.StartDownload(); // 自动开始下载
                    }
                    break;
                case UpgradeStatus.Downloading:
                    // 升级开始时，标记为 “升级中”，禁止关闭
                    lblStatus.Text = "正在下载升级文件...";
                    btnPostpone.Enabled = false; // 下载中禁用推迟按钮
                    _isUpgrading = true; // 开启禁止关闭标记
                    break;
                case UpgradeStatus.DownloadSuccess:
                    lblStatus.Text = "下载完成，准备安装...";
                    progressInstall.Visible = true;
                    lblInstallProgress.Visible = true;
                    break;
                case UpgradeStatus.Upgrading:
                    // 安装过程中，保持 “升级中” 标记
                    lblStatus.Text = "正在安装升级...";
                    _isUpgrading = true; // 确保标记为 true
                    break;
                case UpgradeStatus.UpgradeSuccess:
                    // 核心修复：升级成功后，立即标记为 “非升级中”，允许关闭
                    lblStatus.Text = "升级完成，5 秒后自动关闭...";
                    _isUpgrading = false; // 关键：关闭禁止关闭标记
                    btnPostpone.Enabled = false;

                    // 显示成功通知（5 秒后消失）
                    ShowNotificationWindow( title: "升级成功",
                                            content: "程序升级已完成，窗口将自动关闭",
                                            type: NotificationType.Success
                                         );
                    // 启动主窗口自动关闭计时器（5 秒后关闭）
                    _mainFormCloseTimer.Start();
                    break;
                case UpgradeStatus.UpgradeFailed:
                    // 失败时同样标记为 “非升级中”
                    lblStatus.Text = "升级失败，5 秒后自动关闭...";
                    btnPostpone.Enabled = true;
                    _isUpgrading = false; // 确保允许关闭

                    ShowNotificationWindow( title: "升级失败",
                                            content: "安装过程中出现错误 \n・安装文件被占用 \n・系统权限不足",
                                            type: NotificationType.Error
                                        );
                    _mainFormCloseTimer.Start();
                    break;
                case UpgradeStatus.PreUpgradeVersionEqual:
                    lblStatus.Text = "当前已是最新版本";
                    btnPostpone.Text = "关闭"; // 版本相同时改为关闭按钮
                    break;
                case UpgradeStatus.DownloadFailed:
                    lblStatus.Text = "下载失败，请重试";
                    btnPostpone.Enabled = true;
                    _isUpgrading = false;
                    break;
            }

            if (_upgradeManager.GetServerConfig() != null &&
                !string.IsNullOrEmpty(_upgradeManager.GetServerConfig().UpgradeFileDescription))
            {
                txtDescription.Text = $"本次更新内容：\n{_upgradeManager.GetServerConfig().UpgradeFileDescription}";
            }
        }

        /// <summary>
        /// 显示无确认按钮的通知窗口（确保内容可见）
        /// </summary>
        private void ShowNotificationWindow(string title, string content, NotificationType type)
        {
            // 验证内容不为空（避免传空导致不显示）
            if (string.IsNullOrEmpty(content))
            {
                content = "操作已完成"; // 默认为空时显示的内容
            }

            var notificationForm = new NotificationForm(
                title: title,
                content: content,
                displayDuration: 5000,
                type: type
            );

            // 定位到主窗口中央
            Point mainFormCenter = new Point(
                this.Left + this.Width / 2,
                this.Top + this.Height / 2
            );
            notificationForm.StartPosition = FormStartPosition.Manual;
            notificationForm.Location = new Point(
                mainFormCenter.X - notificationForm.Width / 2,
                mainFormCenter.Y - notificationForm.Height / 2
            );

            notificationForm.Show(this);
        }

        private void OnDownloadProgressChanged(int progress)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<int>(OnDownloadProgressChanged), progress);
                return;
            }
            progressDownload.Value = progress;
            lblDownloadProgress.Text = $"下载进度：{progress}%";
        }

        private void OnInstallProgressChanged(int progress)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<int>(OnInstallProgressChanged), progress);
                return;
            }
            progressInstall.Value = progress;
            lblInstallProgress.Text = $"安装进度：{progress}%";
        }

        private void OnStatusMessageUpdated(string message)
        {
            if (this.InvokeRequired)
            {
                this.Invoke(new Action<string>(OnStatusMessageUpdated), message);
                return;
            }
            lblStatus.Text = message;
        }

        // 移除btnUpgrade_Click事件处理方法

        private void btnPostpone_Click(object sender, EventArgs e)
        {
            if (_upgradeManager.CurrentStatus == UpgradeStatus.PreUpgradeVersionEqual)
            {
                this.Close();
            }
            else
            {
                _upgradeManager.PostponeUpgrade();
                this.Close();
            }
        }

        /// <summary>
        /// 主窗口关闭前处理（仅在真正升级中时禁止关闭）
        /// </summary>
        private void UpgradeForm_FormClosing(object sender, FormClosingEventArgs e)
        {
            // 仅当_isUpgrading 为 true（正在下载 / 安装）时，才禁止关闭
            if (_isUpgrading)
            {
                e.Cancel = true;
                ShowNotificationWindow( title: "提示",
                                        content: "正在升级中，请勿关闭窗口",
                                        type: NotificationType.Info
                                     );
                return;
            }

            // 非升级中状态：清理资源并允许关闭
            _mainFormCloseTimer?.Stop();
            _mainFormCloseTimer?.Dispose();
        }
    }

    // 通知类型枚举
    public enum NotificationType
    {
        Success,
        Error,
        Info
    }

    /// <summary>
    /// 无确认按钮的通知窗口（修复内容显示问题）
    /// </summary>
    public class NotificationForm : Form
    {
        private readonly int _displayDuration;
        private Timer _autoCloseTimer;

        public NotificationForm(string title, string content, int displayDuration, NotificationType type)
        {
            _displayDuration = displayDuration;
            // 关键：先设置窗口尺寸，再初始化控件（确保控件能正确获取窗口尺寸）
            this.Size = new Size(320, 180);
            InitializeNotificationUI(title, content, type);
            InitializeAutoCloseTimer();
        }

        /// <summary>
        /// 初始化通知窗口UI（修复内容不显示的核心调整）
        /// </summary>
        private void InitializeNotificationUI(string title, string content, NotificationType type)
        {
            // 窗口基础属性
            this.FormBorderStyle = FormBorderStyle.None;
            this.ShowInTaskbar = false;
            this.TopMost = true;
            this.BackColor = Color.White;
            this.Padding = new Padding(15);
            this.ForeColor = Color.Black; // 确保文本颜色与背景色对比明显

            // 1. 图标控件（右侧）
            var picIcon = new PictureBox
            {
                Size = new Size(40, 40), // 固定图标大小
                SizeMode = PictureBoxSizeMode.CenterImage,
                Location = new Point(this.Width - 60, 20) // 手动定位到右侧，避免覆盖文本
            };

            // 2. 标题标签（顶部）
            var lblTitle = new Label
            {
                Text = title,
                Font = new Font("微软雅黑", 12F, FontStyle.Bold),
                Location = new Point(15, 15), // 左上角定位
                Size = new Size(this.Width - 80, 30), // 宽度减去图标和边距，避免被图标覆盖
                TextAlign = ContentAlignment.MiddleLeft
            };

            // 3. 内容标签（标题下方，核心修复）
            var lblContent = new Label
            {
                Text = content, // 确保文本包含换行符（\n）
                Font = new Font("微软雅黑", 9F),
                Location = new Point(15, 50), // 位于标题下方
                Size = new Size(this.Width - 80, 100), // 足够的宽度和高度
                TextAlign = ContentAlignment.TopLeft, // 顶部对齐，避免文本被截断
                AutoSize = false // 关闭自动大小，使用手动设置的尺寸
            };

            // 设置图标和标题颜色
            switch (type)
            {
                case NotificationType.Success:
                    lblTitle.ForeColor = Color.FromArgb(46, 204, 113);
                    picIcon.Image = SystemIcons.Information.ToBitmap();
                    break;
                case NotificationType.Error:
                    lblTitle.ForeColor = Color.FromArgb(231, 76, 60);
                    picIcon.Image = SystemIcons.Error.ToBitmap();
                    break;
                case NotificationType.Info:
                    lblTitle.ForeColor = Color.FromArgb(52, 152, 219);
                    picIcon.Image = SystemIcons.Information.ToBitmap();
                    break;
            }

            // 关键：按正确顺序添加控件（先添加底层控件）
            this.Controls.Add(lblContent); // 内容在最底层
            this.Controls.Add(lblTitle);   // 标题在内容上方
            this.Controls.Add(picIcon);    // 图标在最上层（右侧）
        }

        private void InitializeAutoCloseTimer()
        {
            _autoCloseTimer = new Timer();
            _autoCloseTimer.Interval = _displayDuration;
            _autoCloseTimer.Tick += (sender, e) =>
            {
                _autoCloseTimer.Stop();
                this.Close();
            };
            _autoCloseTimer.Start();
        }

        protected override void OnFormClosing(FormClosingEventArgs e)
        {
            base.OnFormClosing(e);
            _autoCloseTimer?.Dispose();
        }
    }
}
